/**
* Copyright (c)  2023 Ultipa, Inc. All rights reserved.
* Created by root on 12/29/23.
* Description
**/

#include "lolog/include/Lolog.h"
#include "MdSpiImpl.h"

namespace lyctp{
    using namespace lolog;
    void MdSpiImpl::OnFrontConnected() {
        LOINFO() << "=====FrontConnected=====" << endl;
        // 开始登录
        CThostFtdcReqUserLoginField loginReq;
        memset(&loginReq, 0, sizeof(loginReq));
        strcpy(loginReq.BrokerID, m_broker_id);
        strcpy(loginReq.UserID, m_invester_id);
        strcpy(loginReq.Password, m_invester_password);
        static int requestID = 0; // 请求编号
        int rt = m_md_user_api->ReqUserLogin(&loginReq, requestID);
        if (!rt)
            LOINFO() << ">>>>>>ReqUserLogin Success" << std::endl;
        else {
            LOWARN() << "--->>>ReqUserLogin Failed" << std::endl;
//            kIsRunning = false;
        }
    }


    void MdSpiImpl::OnFrontDisconnected(int nReason) {
        LOWARN() << "=====FrontDisconnected=====" << std::endl;
        LOWARN() << "nReason： " << nReason << std::endl;
//        kIsRunning = false;
    }

    void MdSpiImpl::OnHeartBeatWarning(int nTimeLapse) {
        LOWARN() << "=====HeartBeatWarning=====" << std::endl;
        LOWARN() << "TimeLapse： " << nTimeLapse << std::endl;
    }

    void MdSpiImpl::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin,
                                   CThostFtdcRspInfoField *pRspInfo,
                                   int nRequestID,
                                   bool bIsLast) {
        bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
        if (!bResult) {
            LOINFO() << "=====RspUserLogin Sucess=====" << std::endl;
            LOINFO() << "TradingDay： " << pRspUserLogin->TradingDay << std::endl;
            LOINFO() << "LoginTime： " << pRspUserLogin->LoginTime << std::endl;
            LOINFO() << "BrokerID： " << pRspUserLogin->BrokerID << std::endl;
            LOINFO() << "UserID： " << pRspUserLogin->UserID << std::endl;
            // 开始订阅行情
            int rt = m_md_user_api->SubscribeMarketData(m_instrument_id, m_instrument_num);
            if (!rt)
                LOINFO() << ">>>>>>SubscribeMarketData Sucess" << std::endl;
            else
                LOWARN() << "--->>>SubscribeMarketData Failed" << std::endl;
        } else
            LOWARN() << "ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl;
    }

    void MdSpiImpl::OnRspUserLogout(
            CThostFtdcUserLogoutField *pUserLogout,
            CThostFtdcRspInfoField *pRspInfo,
            int nRequestID,
            bool bIsLast) {
        bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
        if (!bResult) {
            LOINFO() << "=====RspUserLogout Sucess=====" << std::endl;
            LOINFO() << "BrokerID： " << pUserLogout->BrokerID << std::endl;
            LOINFO() << "UserID： " << pUserLogout->UserID << std::endl;
        } else
            LOWARN() << "ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl;
    }

    void MdSpiImpl::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {
        bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
        if (bResult)
            LOWARN() << "ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl;
    }

    void MdSpiImpl::OnRspSubMarketData(
            CThostFtdcSpecificInstrumentField *pSpecificInstrument,
            CThostFtdcRspInfoField *pRspInfo,
            int nRequestID,
            bool bIsLast) {
        bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
        if (!bResult) {
            LOINFO() << "=====RspSubMarketData Sucess=====" << std::endl;
            LOINFO() << "InstrumentID： " << pSpecificInstrument->InstrumentID << std::endl;
            //init file header
            char filePath[100] = {'\0'};
            sprintf(filePath, "%s_market_data.csv", pSpecificInstrument->InstrumentID);
            std::ofstream outFile;
            outFile.open(filePath, std::ios::out); // 新开文件
            outFile << "合约代码" << ","
                    << "更新时间" << ","
                    << "最新价" << ","
                    << "成交量" << ","
                    << "买价一" << ","
                    << "买量一" << ","
                    << "卖价一" << ","
                    << "卖量一" << ","
                    << "持仓量" << ","
                    << "换手率"
                    << std::endl;
            outFile.close();
        } else{
            LOWARN() << "返回错误--->>> ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl;
        }
    }

// 取消订阅行情应答
    void MdSpiImpl::OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument,
                                         CThostFtdcRspInfoField *pRspInfo,
                                         int nRequestID,
                                         bool bIsLast) {
        bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
        if (!bResult) {
            LOINFO() << "=====RspUnSubMarketData Sucess=====" << std::endl;
            LOINFO() << "InstrumentID： " << pSpecificInstrument->InstrumentID << std::endl;
        } else
            LOWARN() << "ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl;
    }

    void MdSpiImpl::OnRspSubForQuoteRsp(
            CThostFtdcSpecificInstrumentField *pSpecificInstrument,
            CThostFtdcRspInfoField *pRspInfo,
            int nRequestID,
            bool bIsLast) {
        bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
        if (!bResult) {
            LOINFO() << "=====RspSubForQuoteRsp Sucess=====" << std::endl;
            LOINFO() << "InstrumentID： " << pSpecificInstrument->InstrumentID << std::endl;
        } else
            LOWARN() << "ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl;
    }

    void MdSpiImpl::OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpecificInstrument,
                                          CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {
        bool bResult = pRspInfo && (pRspInfo->ErrorID != 0);
        if (!bResult) {
            LOINFO() << "=====RspUnSubForQuoteRsp Sucess=====" << std::endl;
            LOINFO() << "InstrumentID： " << pSpecificInstrument->InstrumentID << std::endl;
        } else
            LOWARN() << "ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl;
    }

    void MdSpiImpl::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData) {
        //push to the queue
        m_current_md_cache[pDepthMarketData->InstrumentID] = *pDepthMarketData;

        //write circle queue
        LyMsg msg;
        if (!msg.write((char*)pDepthMarketData, 1, sizeof(CThostFtdcDepthMarketDataField), m_circle_buffer)) {
            cerr << "Circle buffer is full" << endl;
        }
    }

    void MdSpiImpl::OnRtnForQuoteRsp(CThostFtdcForQuoteRspField *pForQuoteRsp) {
        // 部分询价结果
        LOINFO() << "=====RtnForQuoteRsp=====" << std::endl;
        LOINFO() << "TradingDay： " << pForQuoteRsp->TradingDay << std::endl;
        LOINFO() << "ExchangeID： " << pForQuoteRsp->ExchangeID << std::endl;
        LOINFO() << "InstrumentID： " << pForQuoteRsp->InstrumentID << std::endl;
        LOINFO() << "ForQuoteSysID： " << pForQuoteRsp->ForQuoteSysID << std::endl;
    }

}